package com.bnyy.medicalHousekeeper.request;

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.bnyy.health.HealthDataRetrofitService;
import com.bnyy.medicalHousekeeper.BuildConfig;
import com.bnyy.medicalHousekeeper.R;
import com.bnyy.medicalHousekeeper.request.service.JavaRetrofitService;
import com.bnyy.medicalHousekeeper.request.service.RetrofitService;
import com.bnyy.common.Constant;
import com.bnyy.common.ResponseData;
import com.bnyy.message.MessageRetrofitService;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class RequestManager {

    private static final String TAG = "RequestManager";
    @SuppressLint("StaticFieldLeak")
    private static RequestManager instance;
    //    private _RetrofitService mRetrofitService;
    private static String mUserAgent = "", mToken = "", mCokkie = "";
    private static Context context;
    public RetrofitService
            mRetrofitService,
            mRetrofitServiceServer;
    public JavaRetrofitService mJavaRetrofitService;
    public MessageRetrofitService mMessageRetrofitService;
    public HealthDataRetrofitService mHealthDataRetrofitService;

    public void init(Context context) {
        if (RequestManager.context != null) {
            return;
        }
        RequestManager.context = context;

        SharedPreferences sharedPreferences = context.getSharedPreferences(Constant.SP_NAME, Context.MODE_PRIVATE);

        mCokkie = sharedPreferences.getString(Constant.SpTag.TOKEN, "");
        if (mCokkie.contains(";")) {
            mCokkie = mCokkie.split(";")[1];
        }
        String[] split = mCokkie.split("token=");
        if (split.length == 2) {
            mToken = split[1];
        }

        String deviceUuid = sharedPreferences.getString(Constant.SpTag.DEVICE_UUID, "");
        if (TextUtils.isEmpty(deviceUuid)) {
            deviceUuid = UUID.randomUUID().toString();
            sharedPreferences.edit().putString(Constant.SpTag.DEVICE_UUID, deviceUuid).apply();
        }

        mUserAgent = BuildConfig.APPLICATION_ID
                + "/v" + BuildConfig.VERSION_NAME + "_"
                + new SimpleDateFormat("yyyyMMdd").format(new Date())
                + "("
                + Build.PRODUCT + ";"
                + Build.MODEL
                + BuildConfig.VERSION_NAME + ";"
                + "UUID/" + deviceUuid
                + ")"
                + ";apptype=" + 6; // // 1 用户端 2 医护端 3 长护险管家 6 医养管家

        SharedPreferences sp = context.getSharedPreferences(Constant.SP_NAME, Context.MODE_PRIVATE);
        String baseUrl = sp.getString(Constant.SpTag.BASE_URL, Constant.NetWork.BASE_URL_FORMAL);
//        String baseUrl = Constant.NetWork.BASE_URL_TEST;
        initBaseUrl(baseUrl);
    }

    private OkHttpClient getOkhttpClient() {
        int timeout = 30;
        return new OkHttpClient.Builder()
                .connectTimeout(timeout, TimeUnit.SECONDS)
                .readTimeout(timeout, TimeUnit.SECONDS)
                .writeTimeout(timeout, TimeUnit.SECONDS)
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request();
                        Request.Builder builder = request.newBuilder();

                        builder.addHeader("User-Agent", mUserAgent);
                        if (!TextUtils.isEmpty(mCokkie)) {
                            builder.addHeader("Cookie", mCokkie);
                        }

                        request = builder.build();
                        Headers headers = request.headers();

                        Response response = chain.proceed(request);
                        ResponseBody responseBody = response.body();

                        StringBuilder sb = new StringBuilder();
                        sb.append("{")
                                .append("\n")
                                .append(request.method()).append(" ").append(request.url().toString())
                                .append("\n");


                        if (request.body() != null) {
                            Buffer buffer = new Buffer();
                            try {
                                request.body().writeTo(buffer);
                                String params = buffer.readString(Charset.forName("UTF-8"));
                                sb.append("request params : ").append(params).append("\n");
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }

                        if (headers.size() > 0) {
                            sb.append("header : {")
                                    .append("\n");
                            Map<String, List<String>> map = headers.toMultimap();
                            for (Map.Entry<String, List<String>> entry : map.entrySet()) {
                                sb.append(entry.getKey()).append(" : ").append(entry.getValue().toString()).append("\n");
                            }
                            sb.append("}");
                        }

                        if (responseBody != null) {
                            MediaType mediaType = responseBody.contentType();
                            String content = responseBody.string();
                            sb.append("\n")
                                    .append(response.code())
                                    .append(" ").append(content);
                            response = response.newBuilder().body(ResponseBody.create(mediaType, content)).build();
                        }
                        sb.append("\n")
                                .append("}");
                        Log.e(TAG, sb.toString());
                        return response;
                    }
                })
                .build();
    }

    public static RequestManager getInstance() {
        if (instance == null) {
            instance = new RequestManager();
        }
        return instance;
    }

    private RequestManager() {

    }

    private String baseUrl;

    public String getBaseUrl() {
        return baseUrl;
    }

    public boolean isFormal() {
        boolean isFormal = baseUrl.equals(Constant.NetWork.BASE_URL_FORMAL);
        Log.e(TAG, "baseUrl = " + baseUrl + " isFormal = " + isFormal);
        return isFormal;
    }

    public void initBaseUrl(String baseUrl) {
        Log.e(TAG, "baseUrl = " + baseUrl);

        this.baseUrl = baseUrl;
//        App.setGlobalParams(null);
        SharedPreferences sp = context.getSharedPreferences(Constant.SP_NAME, Context.MODE_PRIVATE);
        sp.edit().putString(Constant.SpTag.BASE_URL, baseUrl).apply();

        String baseUrlJava = baseUrl + Constant.NetWork.BASE_URL_JAVA;
        String baseUrlServer = baseUrl + Constant.NetWork.BASE_URL_SERVER;

        mRetrofitService = get(baseUrl, RetrofitService.class);

        mRetrofitServiceServer = get(baseUrlServer, RetrofitService.class);

        mJavaRetrofitService = get(baseUrlJava, JavaRetrofitService.class);

        mMessageRetrofitService = get(baseUrlJava, MessageRetrofitService.class);

        mHealthDataRetrofitService = get(baseUrlJava, HealthDataRetrofitService.class);
    }

    private <T> T get(String baseUrl, Class<T> t) {
        return new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(getOkhttpClient())
                .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build().create(t);
    }

    public <T> void request(Observable<ResponseData<T>> observable, Observer<T> observer) {
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new ResponseDataFunc1<>(observer))
                .subscribe(observer);
    }

    public <T> void requestNormal(Observable<T> observable, Observer<T> observer) {
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    // 多个请求合并为一个请求同步请求,一个请求失败则所有请求失败
    public void request(Observer observer, Observable... observables) {
        Observable.merge(observables)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new ResponseDataFunc1<>(observer))
                .subscribe(observer);
    }

    public <T> void requestByXUtils(String url, XUtilsRequestCallback callback) {
        RequestParams params = new RequestParams(url);
        x.http().get(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                callback.onSuccess(result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                ex.printStackTrace();
                callback.onError(ex, isOnCallback);
            }

            @Override
            public void onCancelled(CancelledException cex) {
                cex.printStackTrace();
            }

            @Override
            public void onFinished() {
                Log.e(TAG, "requestByXUtils onFinished");
            }
        });
    }

    public static RequestBody getJsonRequestBody(Object o) {
        String json = new Gson().toJson(o);
        return RequestBody.create(MediaType.parse("Content-Type, application/json"), json);
    }

    public static void setToken(String token) {
        if (!TextUtils.isEmpty(token)) {
            mCokkie = "token=" + token;
            mToken = token;
            SharedPreferences.Editor config = context.getSharedPreferences(Constant.SP_NAME, Context.MODE_PRIVATE).edit();
            config.putString(Constant.SpTag.TOKEN, token);
            config.apply();
        }
    }

    public static String getmCokkie() {
        return mCokkie;
    }

    public static String getToken() {
        return mToken;
    }

    public void download(Context context, String url, String path, DownloadCallbackImpl callback) {
        Log.e(TAG, "download url = " + url + " path = " + path);
        RequestParams requestParams = new RequestParams(url);
        requestParams.setSaveFilePath(path);
        // 下载完成后自动为文件命名
        // requestParams.setAutoRename(true);
        x.http().get(requestParams, callback);
    }

    public static abstract class DownloadCallbackImpl implements org.xutils.common.Callback.ProgressCallback<File> {

        private Context context;
        private ProgressDialog progressDialog = null;

        public DownloadCallbackImpl(Context context) {
            this(context, true);
        }

        public DownloadCallbackImpl(Context context, boolean showProgressDialog) {
            this.context = context;
            if (showProgressDialog) {
                if (progressDialog == null) {
                    progressDialog = new ProgressDialog(context);
                    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                    progressDialog.setCancelable(false);
                    progressDialog.setTitle("正在下载，请保持屏幕常亮");
//                    progressDialog.setMax((int) (total / 1000));
                    progressDialog.setIcon(R.mipmap.icon_logo);
                    progressDialog.show();
                }
            }
        }

        @Override
        public void onWaiting() {
            Log.e(TAG, "等待下载");
        }

        @Override
        public void onStarted() {
            Log.e(TAG, "开始下载");
        }

        @Override
        public void onLoading(long total, long current, boolean isDownloading) {
            if (progressDialog != null) {
                progressDialog.setMax((int) (total / 1000));
                progressDialog.setProgress((int) (current / 1000));
            }
        }

        @Override
        public void onSuccess(File result) {
            Log.e(TAG, "下载成功");
            dismissProgressDialog();
        }

        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
            ex.printStackTrace();
            Log.e(TAG, "下载失败");
            dismissProgressDialog();
            Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancelled(CancelledException cex) {
            Log.e(TAG, "取消下载");
            dismissProgressDialog();
            Toast.makeText(context, "取消下载", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onFinished() {
            Log.e(TAG, "结束下载");
            dismissProgressDialog();
//            Toast.makeText(context, "结束下载", Toast.LENGTH_SHORT).show();
        }

        private void dismissProgressDialog() {
            if (progressDialog != null && progressDialog.isShowing()) {
                progressDialog.dismiss();
            }
        }
    }
}































